﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using System.Threading;
using System.Data.SqlClient;
using System.Data.Common;
using Apq_DBTools.Forms;
using Apq.TreeListView;
using System.IO;
using org.mozilla.intl.chardet;
using Apq.DllImports;
using System.Collections;
using MySql.Data.MySqlClient;
using System.Text.RegularExpressions;

namespace Apq_DBTools.Forms
{
	public partial class DBDataCompare : Apq.Windows.Forms.DockDocForm
	{
		private static string _DBCProjectFolder = string.Empty;
		/// <summary>
		/// 连接方案文件夹
		/// </summary>
		private string DBCProjectFolder
		{
			get
			{
				if (string.IsNullOrWhiteSpace(_DBCProjectFolder))
				{
					_DBCProjectFolder = System.IO.Path.GetDirectoryName(Apq.GlobalObject.TheProcess.MainModule.FileName) + @"\DBCProject\MySql";
				}
				if (!Directory.Exists(_DBCProjectFolder))
				{
					Directory.CreateDirectory(_DBCProjectFolder);
				}
				return _DBCProjectFolder;
			}
		}

		private static string _MappingProjectFolder = string.Empty;
		/// <summary>
		/// 映射方案文件夹
		/// </summary>
		private string MappingProjectFolder
		{
			get
			{
				if (string.IsNullOrWhiteSpace(_MappingProjectFolder))
				{
					_MappingProjectFolder = System.IO.Path.GetDirectoryName(Apq.GlobalObject.TheProcess.MainModule.FileName) + @"\MappingProject";
				}
				if (!Directory.Exists(_MappingProjectFolder))
				{
					Directory.CreateDirectory(_MappingProjectFolder);
				}
				return _MappingProjectFolder;
			}
		}

		private Apq.Windows.Forms.ComboBoxItemsHelper cbiHelperDBCProject;
		private Apq.Windows.Forms.ComboBoxItemsHelper cbiHelperMappingProject;

		private Apq.Windows.Forms.DockForms.ErrList ErrList = new Apq.Windows.Forms.DockForms.ErrList();

		public DBDataCompare()
		{
			InitializeComponent();

			//Apq.Windows.Forms.DataGridViewHelper.SetDefaultStyle(dataGridView1);
			Apq.Windows.Forms.DataGridViewHelper.AddBehaivor(dataGridView1);
			Apq.Windows.Forms.DataGridViewHelper.SetDefaultStyle(dataGridView2);
			Apq.Windows.Forms.DataGridViewHelper.AddBehaivor(dataGridView2);
			Apq.Windows.Forms.DataGridViewHelper.SetDefaultStyle(dataGridView3);
			Apq.Windows.Forms.DataGridViewHelper.AddBehaivor(dataGridView3);
			Apq.Windows.Forms.DataGridViewHelper.SetDefaultStyle(dataGridView4);
			Apq.Windows.Forms.DataGridViewHelper.AddBehaivor(dataGridView4);

			cbiHelperDBCProject = new Apq.Windows.Forms.ComboBoxItemsHelper(tscbDBCProject.Items, this);
			cbiHelperMappingProject = new Apq.Windows.Forms.ComboBoxItemsHelper(tscbMappingProject.Items, this);
		}

		public override void SetUILang(Apq.UILang.UILang UILang)
		{
			Text = UILang["数据比较"];

			tsbErrList.Text = UILang["错误列表"];
			ErrList.SetUILang(UILang);

			#region 连接到数据库
			tpDBConnector.Text = UILang["连接到数据库"];

			tslDBCProject.Text = UILang["连接方案"];
			tsbDBCProjectSave.Text = UILang["保存(&S)"];

			groupBox1.Text = UILang["数据库1(目标版本)"];
			mySqlConnector1.SetUILang(UILang);
			groupBox1.Text = UILang["数据库2(基础版本)"];
			mySqlConnector2.SetUILang(UILang);

			btnCopyLeft.Text = UILang["复制(&P)->"];
			btnSwitch.Text = UILang["交换(&W)"];
			btnCopyRight.Text = UILang["<-复制(&Y)"];
			btnGotoMapping.Text = UILang["开始比较(&M)"];
			btnCancel.Text = UILang["取消(&C)"];
			#endregion

			#region 参数设置
			tpMapping.Text = UILang["参数设置"];

			tslMappingProject.Text = UILang["映射方案"];
			tsbMappingProjectSave.Text = UILang["保存(&S)"];

			tssbSelect.Text = UILang["选择"];
			tsmiSelectAll.Text = UILang["全选(&A)"];
			tsmiSelectReverse.Text = UILang["反选(&R)"];

			btnPre1.Text = UILang["上一步(&P)"];
			btnNext1.Text = UILang["下一步(&N)"];
			btnCancel1.Text = UILang["取消(&C)"];

			#region 列
			col_CheckState.HeaderText = UILang["选择"];
			colTableID1.HeaderText = UILang["表1"];
			colTableID2.HeaderText = UILang["表2"];
			colDataKeys.HeaderText = UILang["数据Key"];
			colRowCount.HeaderText = UILang["行数"];

			colColID1.HeaderText = UILang["列1"];
			colColID2.HeaderText = UILang["列2"];
			#endregion

			#endregion
		}

		private void DBDataCompare_Load(object sender, EventArgs e)
		{
			ShowStep(1);
		}

		#region IDataShow 成员
		/// <summary>
		/// 前期准备(如数据库连接或文件等)
		/// </summary>
		public override void InitDataBefore()
		{
			#region 数据库连接
			#endregion
		}
		/// <summary>
		/// 初始数据(如Lookup数据等)
		/// </summary>
		/// <param name="ds"></param>
		public override void InitData(DataSet ds)
		{
			#region 准备数据集结构
			#endregion

			#region 加载所有查找表
			//_xsd.dic_ObjectType.InitData();

			// 读取方案文件列表
			string ProjectName = GlobalObject.XmlConfigChain[this.GetType(), "DBCProjectName"] ?? string.Empty;
			cbiHelperDBCProject.Items_Reset(DBCProjectFolder, "*.xml");
			cbiHelperDBCProject.fsw_Set(DBCProjectFolder, "*.xml");
			cbiHelperDBCProject.fsw.Start();
			tscbDBCProject.SelectedIndex = tscbDBCProject.Items.IndexOf(ProjectName);

			ProjectName = GlobalObject.XmlConfigChain[this.GetType(), "MappingProjectName"] ?? string.Empty;
			cbiHelperMappingProject.Items_Reset(MappingProjectFolder, "*.xml");
			cbiHelperMappingProject.fsw_Set(MappingProjectFolder, "*.xml");
			cbiHelperMappingProject.fsw.Start();
			tscbMappingProject.SelectedIndex = tscbMappingProject.Items.IndexOf(ProjectName);
			#endregion
		}
		/// <summary>
		/// 加载数据
		/// </summary>
		/// <param name="ds"></param>
		public override void LoadData(DataSet ds)
		{
		}
		#endregion

		/// <summary>
		/// 显示第几步
		/// </summary>
		/// <param name="Step"></param>
		public void ShowStep(int Step)
		{
			tabControl1.TabPages.Clear();

			switch (Step)
			{
				case 1:
				default:
					tabControl1.TabPages.Add(tpDBConnector);
					break;
				case 2:
					tabControl1.TabPages.Add(tpMapping);
					break;
			}
		}

		private void DBDataCompare_FormClosing(object sender, FormClosingEventArgs e)
		{
		}

		private void DBDataCompare_Activated(object sender, EventArgs e)
		{
		}

		private void DBDataCompare_Deactivate(object sender, EventArgs e)
		{

		}

		#region 选择

		private void tsmiSelectAll_Click(object sender, EventArgs e)
		{
			dataGridView1.EndEdit();
			foreach (DBDataCompare_XSD.TableMappingRow dr in _xsd.TableMapping.Rows)
			{
				dr._CheckState = 1;
			}
		}

		private void tsmiSelectReverse_Click(object sender, EventArgs e)
		{
			dataGridView1.EndEdit();
			foreach (DBDataCompare_XSD.TableMappingRow dr in _xsd.TableMapping.Rows)
			{
				dr._CheckState = Math.Abs(dr._CheckState - 1);
			}
		}
		#endregion

		private void tsbErrList_Click(object sender, EventArgs e)
		{
			if (tsbErrList.Checked)
			{
				ErrList.Show(DockFrame.DockDoc);
			}
			else
			{
				ErrList.Hide();
			}
		}

		#region 连接复制
		private void btnCopyLeft_Click(object sender, EventArgs e)
		{
			string[] aryDBNames = new string[mySqlConnector1.cbDBName.Items.Count];
			mySqlConnector1.cbDBName.Items.CopyTo(aryDBNames, 0);
			mySqlConnector2.cbDBName.Items.Clear();
			mySqlConnector2.cbDBName.Items.AddRange(aryDBNames);

			mySqlConnector2.cbName.Text = mySqlConnector1.cbName.Text;
			mySqlConnector2.txtServer.Text = mySqlConnector1.txtServer.Text;
			mySqlConnector2.txtUserId.Text = mySqlConnector1.txtUserId.Text;
			mySqlConnector2.txtPwd.Text = mySqlConnector1.txtPwd.Text;
			mySqlConnector2.txtPort.Text = mySqlConnector1.txtPort.Text;
			mySqlConnector2.cbDBName.Text = mySqlConnector1.cbDBName.Text;
		}

		private void btnSwitch_Click(object sender, EventArgs e)
		{
			string[] aryDBNames1 = new string[mySqlConnector1.cbDBName.Items.Count];
			string[] aryDBNames2 = new string[mySqlConnector2.cbDBName.Items.Count];

			mySqlConnector1.cbDBName.Items.CopyTo(aryDBNames1, 0);
			mySqlConnector2.cbDBName.Items.CopyTo(aryDBNames2, 0);
			mySqlConnector1.cbDBName.Items.Clear();
			mySqlConnector2.cbDBName.Items.Clear();
			mySqlConnector1.cbDBName.Items.AddRange(aryDBNames2);
			mySqlConnector2.cbDBName.Items.AddRange(aryDBNames1);

			string strName1 = mySqlConnector1.cbName.Text;
			string strServer1 = mySqlConnector1.txtServer.Text;
			string strUserId1 = mySqlConnector1.txtUserId.Text;
			string strPwd1 = mySqlConnector1.txtPwd.Text;
			string strPort1 = mySqlConnector1.txtPort.Text;
			string strDBName1 = mySqlConnector1.cbDBName.Text;

			mySqlConnector1.cbName.Text = mySqlConnector2.cbName.Text;
			mySqlConnector1.txtServer.Text = mySqlConnector2.txtServer.Text;
			mySqlConnector1.txtUserId.Text = mySqlConnector2.txtUserId.Text;
			mySqlConnector1.txtPwd.Text = mySqlConnector2.txtPwd.Text;
			mySqlConnector1.txtPort.Text = mySqlConnector2.txtPort.Text;
			mySqlConnector1.cbDBName.Text = mySqlConnector2.cbDBName.Text;

			mySqlConnector2.cbName.Text = strName1;
			mySqlConnector2.txtServer.Text = strServer1;
			mySqlConnector2.txtUserId.Text = strUserId1;
			mySqlConnector2.txtPwd.Text = strPwd1;
			mySqlConnector2.txtPort.Text = strPort1;
			mySqlConnector2.cbDBName.Text = strDBName1;
		}

		private void btnCopyRight_Click(object sender, EventArgs e)
		{
			string[] aryDBNames = new string[mySqlConnector2.cbDBName.Items.Count];
			mySqlConnector1.cbDBName.Items.CopyTo(aryDBNames, 0);
			mySqlConnector1.cbDBName.Items.Clear();
			mySqlConnector1.cbDBName.Items.AddRange(aryDBNames);

			mySqlConnector1.cbName.Text = mySqlConnector2.cbName.Text;
			mySqlConnector1.txtServer.Text = mySqlConnector2.txtServer.Text;
			mySqlConnector1.txtUserId.Text = mySqlConnector2.txtUserId.Text;
			mySqlConnector1.txtPwd.Text = mySqlConnector2.txtPwd.Text;
			mySqlConnector1.txtPort.Text = mySqlConnector2.txtPort.Text;
			mySqlConnector1.cbDBName.Text = mySqlConnector2.cbDBName.Text;
		}
		#endregion

		private void btnGotoMapping_Click(object sender, EventArgs e)
		{
			try
			{
				_MySqlConnection1 = mySqlConnector1.CreateMySqlConnection();
				_MySqlConnection1.Open();

				_MySqlConnection2 = mySqlConnector2.CreateMySqlConnection();
				_MySqlConnection2.Open();

				//+从数据库获取元数据后转到第二页
				ShowStep(2);
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
			finally
			{
				Apq.Data.Common.DbConnectionHelper.Close(_MySqlConnection1);
				Apq.Data.Common.DbConnectionHelper.Close(_MySqlConnection2);
			}
		}

		private void btnCancel_Click(object sender, EventArgs e)
		{
			DockFrame.Close();
		}

		private void tsbDBCProjectSave_Click(object sender, EventArgs e)
		{
			if (string.IsNullOrWhiteSpace(tscbDBCProject.Text))
			{
				return;
			}

			try
			{
				GlobalObject.XmlConfigChain[this.GetType(), "DBCProjectName"] = tscbDBCProject.Text;
				GlobalObject.XmlConfigChain.Save();

				//获取界面值，加密密码后生成连接文件，覆盖保存
				DBDataCompareProject_XSD xsd = new DBDataCompareProject_XSD();
				DBDataCompareProject_XSD.MySqlRow dr = xsd.MySql.NewMySqlRow();
				xsd.MySql.Rows.Add(dr);

				#region 左侧
				dr.DBCFileName1 = mySqlConnector1.cbName.Text;
				dr.Server1 = mySqlConnector1.txtServer.Text;
				dr["Port1"] = mySqlConnector1.txtPort.Text;
				dr.Uid1 = mySqlConnector1.txtUserId.Text;
				dr.PwdD1 = mySqlConnector1.txtPwd.Text;
				if (!string.IsNullOrWhiteSpace(mySqlConnector1.cbDBName.Text))
				{
					dr.DBName1 = mySqlConnector1.cbDBName.Text;
				}
				if (mySqlConnector1.cbSavePwd.Checked)
				{
					dr["PwdC1"] = Apq.Security.Cryptography.DESHelper.EncryptString(mySqlConnector1.txtPwd.Text,
						Apq.Win.GlobalObject.XmlAsmConfig["Apq.Win.GlobalObject", "DESKey"],
						Apq.Win.GlobalObject.XmlAsmConfig["Apq.Win.GlobalObject", "DESIV"]
					);
				}

				xsd.MySql.Columns.Remove("PwdD1");
				if (!mySqlConnector1.cbSavePwd.Checked)
				{
					xsd.MySql.Columns.Remove("PwdC1");
				}
				#endregion
				#region 右侧
				dr.DBCFileName2 = mySqlConnector2.cbName.Text;
				dr.Server2 = mySqlConnector2.txtServer.Text;
				dr["Port2"] = mySqlConnector2.txtPort.Text;
				dr.Uid2 = mySqlConnector2.txtUserId.Text;
				dr.PwdD2 = mySqlConnector2.txtPwd.Text;
				if (!string.IsNullOrWhiteSpace(mySqlConnector2.cbDBName.Text))
				{
					dr.DBName2 = mySqlConnector2.cbDBName.Text;
				}
				if (mySqlConnector2.cbSavePwd.Checked)
				{
					dr["PwdC2"] = Apq.Security.Cryptography.DESHelper.EncryptString(mySqlConnector2.txtPwd.Text,
						Apq.Win.GlobalObject.XmlAsmConfig["Apq.Win.GlobalObject", "DESKey"],
						Apq.Win.GlobalObject.XmlAsmConfig["Apq.Win.GlobalObject", "DESIV"]
					);
				}

				xsd.MySql.Columns.Remove("PwdD2");
				if (!mySqlConnector2.cbSavePwd.Checked)
				{
					xsd.MySql.Columns.Remove("PwdC2");
				}
				#endregion

				xsd.MySql.WriteXml(DBCProjectFolder + @"\" + tscbDBCProject.Text + ".xml", XmlWriteMode.IgnoreSchema);
			}
			catch (System.Exception ex)
			{
				MessageBox.Show(this, ex.Message);
			}
		}

		private void tscbDBCProject_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (!Apq.GlobalObject.EventSuspend.Contains(new Apq.CSMember(tscbDBCProject, "SelectedIndexChanged")))
			{
				try
				{
					GlobalObject.XmlConfigChain[this.GetType(), "DBCProjectName"] = tscbDBCProject.Text;
					GlobalObject.XmlConfigChain.Save();

					mySqlConnector1.SetUIDefault();
					mySqlConnector2.SetUIDefault();

					//打开连接文件解密密码并对界面赋值
					DBDataCompareProject_XSD xsd = new DBDataCompareProject_XSD();
					xsd.MySql.ReadXml(DBCProjectFolder + @"\" + tscbDBCProject.Text + ".xml");
					if (xsd.MySql.Rows.Count > 0)
					{
						DBDataCompareProject_XSD.MySqlRow dr = xsd.MySql.Rows[0] as DBDataCompareProject_XSD.MySqlRow;
						dr.PwdD1 = Apq.Security.Cryptography.DESHelper.DecryptString(Apq.Convert.ChangeType<string>(dr["PwdC1"]),
							Apq.Win.GlobalObject.XmlAsmConfig["Apq.Win.GlobalObject", "DESKey"],
							Apq.Win.GlobalObject.XmlAsmConfig["Apq.Win.GlobalObject", "DESIV"]
						);
						dr.PwdD2 = Apq.Security.Cryptography.DESHelper.DecryptString(Apq.Convert.ChangeType<string>(dr["PwdC2"]),
							Apq.Win.GlobalObject.XmlAsmConfig["Apq.Win.GlobalObject", "DESKey"],
							Apq.Win.GlobalObject.XmlAsmConfig["Apq.Win.GlobalObject", "DESIV"]
						);

						#region 左侧
						Apq.GlobalObject.EventSuspend.AddUnique(new Apq.CSMember(mySqlConnector1.cbName, "SelectedIndexChanged"));
						Apq.GlobalObject.EventSuspend.AddUnique(new Apq.CSMember(mySqlConnector1.txtServer, "TextUpdate"));
						Apq.GlobalObject.EventSuspend.AddUnique(new Apq.CSMember(mySqlConnector1.cbDBName, "TextUpdate"));
						Apq.GlobalObject.EventSuspend.AddUnique(new Apq.CSMember(mySqlConnector1.cbDBName, "SelectedIndexChanged"));
						mySqlConnector1.cbName.SelectedIndex = mySqlConnector1.cbName.Items.IndexOf(dr.DBCFileName1);
						mySqlConnector1.txtServer.Text = dr.Server1;
						mySqlConnector1.txtUserId.Text = dr.Uid1;
						mySqlConnector1.txtPwd.Text = dr.PwdD1;
						mySqlConnector1.txtPort.Text = dr.Port1;
						if (!dr.IsDBName1Null())
						{
							mySqlConnector1.cbDBName.Text = dr.DBName1;
						}
						Apq.GlobalObject.EventSuspend.Remove(new Apq.CSMember(mySqlConnector1.cbDBName, "SelectedIndexChanged"));
						Apq.GlobalObject.EventSuspend.Remove(new Apq.CSMember(mySqlConnector1.cbDBName, "TextUpdate"));
						Apq.GlobalObject.EventSuspend.Remove(new Apq.CSMember(mySqlConnector1.txtServer, "TextUpdate"));
						Apq.GlobalObject.EventSuspend.Remove(new Apq.CSMember(mySqlConnector1.cbName, "SelectedIndexChanged"));
						#endregion
						#region 右侧
						Apq.GlobalObject.EventSuspend.AddUnique(new Apq.CSMember(mySqlConnector2.cbName, "SelectedIndexChanged"));
						Apq.GlobalObject.EventSuspend.AddUnique(new Apq.CSMember(mySqlConnector2.txtServer, "TextUpdate"));
						Apq.GlobalObject.EventSuspend.AddUnique(new Apq.CSMember(mySqlConnector2.cbDBName, "TextUpdate"));
						Apq.GlobalObject.EventSuspend.AddUnique(new Apq.CSMember(mySqlConnector2.cbDBName, "SelectedIndexChanged"));
						mySqlConnector2.cbName.SelectedIndex = mySqlConnector1.cbName.Items.IndexOf(dr.DBCFileName2);
						mySqlConnector2.txtServer.Text = dr.Server2;
						mySqlConnector2.txtUserId.Text = dr.Uid2;
						mySqlConnector2.txtPwd.Text = dr.PwdD2;
						mySqlConnector2.txtPort.Text = dr.Port2;
						if (!dr.IsDBName2Null())
						{
							mySqlConnector2.cbDBName.Text = dr.DBName2;
						}
						Apq.GlobalObject.EventSuspend.Remove(new Apq.CSMember(mySqlConnector2.cbDBName, "SelectedIndexChanged"));
						Apq.GlobalObject.EventSuspend.Remove(new Apq.CSMember(mySqlConnector2.cbDBName, "TextUpdate"));
						Apq.GlobalObject.EventSuspend.Remove(new Apq.CSMember(mySqlConnector2.txtServer, "TextUpdate"));
						Apq.GlobalObject.EventSuspend.Remove(new Apq.CSMember(mySqlConnector2.cbName, "SelectedIndexChanged"));
						#endregion

						//btnSave.Enabled = false;
					}
				}
				catch (System.Exception ex)
				{
					MessageBox.Show(this, ex.Message);
				}
			}
		}

		private void btnPre1_Click(object sender, EventArgs e)
		{
			ShowStep(1);
		}
	}
}